package ks

import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"
)

var Acctoken string

// GetRandStr 获取随机字符串
func GetRandStr() string {
	rand.Seed(time.Now().UnixNano())
	charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	randomString := make([]byte, 10)
	for i := range randomString {
		randomString[i] = charset[rand.Intn(len(charset))]
	}
	return string(randomString)
}

// GetAccessToken 获取AccessToken
func GetAccessToken(appid, appsecret string) (string, error) {
	// 设置请求参数
	params := url.Values{}
	params.Set("app_id", appid)
	params.Set("app_secret", appsecret)
	params.Set("grant_type", "client_credentials")

	// 发送POST请求
	resp, err := http.PostForm("https://open.kuaishou.com/oauth2/access_token", params)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	// 处理响应结果
	body, err := ioutil.ReadAll(resp.Body)
	var tokenResponse AccessTokenResponse
	err = json.Unmarshal(body, &tokenResponse)
	if err != nil {
		return "", err
	}
	if tokenResponse.Result != 1 {
		return "", err
	}
	return tokenResponse.AccessToken, nil
}

// GetSign 获取签名
func GetSign(params map[string]string, appSecret string) string {
	// 将参数名按字典序升序排序
	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	// 拼接参数名和参数值
	var sb strings.Builder
	for i, k := range keys {
		sb.WriteString(k)
		sb.WriteString("=")
		sb.WriteString(params[k])
		if i < len(keys)-1 {
			sb.WriteString("&")
		}
	}
	sb.WriteString(appSecret)
	str := sb.String()
	// 计算MD5值
	h := md5.New()
	h.Write([]byte(str))
	sign := hex.EncodeToString(h.Sum(nil))
	return sign
}

// BindRoom 启动绑定直播间
func BindRoom(appid, appSecret, roomCode, roundId string) BindRoomRes {
	url := "https://open.kuaishou.com/openapi/developer/live/data/task/start" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	Sign := GetSign(map[string]string{
		"app_id":    appid,
		"roomCode":  roomCode,
		"roundId":   roundId,
		"timestamp": strconv.FormatInt(timestamp/1e6, 10),
	}, appSecret)

	data := BindRoomReq{
		RoomCode:  roomCode,
		Timestamp: timestamp,
		Sign:      Sign,
		RoundId:   roundId,
	}
	marshal, _ := json.Marshal(data)

	payload := strings.NewReader(string(marshal))

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp BindRoomRes
	json.Unmarshal(body, &resp)
	return resp
}

// UnBindRoom 解绑直播间
func UnBindRoom(appid, appSecret, roomCode, roundId string) UnBindRoomRes {
	url := "https://open.kuaishou.com/openapi/developer/live/data/task/stop" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	Sign := GetSign(map[string]string{
		"app_id":    appid,
		"roomCode":  roomCode,
		"roundId":   roundId,
		"timestamp": strconv.FormatInt(timestamp/1e6, 10),
	}, appSecret)

	data := BindRoomReq{
		RoomCode:  roomCode,
		Timestamp: timestamp,
		Sign:      Sign,
		RoundId:   roundId,
	}
	marshal, _ := json.Marshal(data)

	payload := strings.NewReader(string(marshal))

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp UnBindRoomRes
	json.Unmarshal(body, &resp)
	return resp
}

// QueryLiveStatus 查询绑定直播间任务状态
func QueryLiveStatus(appid, appSecret, roomCode string) QueryStatusRes {
	url := "https://open.kuaishou.com/openapi/developer/live/data/task/status" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	Sign := GetSign(map[string]string{
		"app_id":    appid,
		"roomCode":  roomCode,
		"timestamp": strconv.FormatInt(timestamp/1e6, 10),
	}, appSecret)

	data := QueryStatusReq{
		RoomCode:  roomCode,
		Timestamp: timestamp,
		Sign:      Sign,
	}
	marshal, _ := json.Marshal(data)

	payload := strings.NewReader(string(marshal))

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp QueryStatusRes
	json.Unmarshal(body, &resp)
	return resp
}

/*
[{"id":11582,"effectDesc":"送一个召唤魔法师，送5个进化大魔法师","batchBar":{"subTitle":"攻击利器","batchInfos":[{"count":1,"action":"召唤","objectBeingActed":"魔法师x1"},{"count":5,"action":"进化","objectBeingActed":"大魔法师"},{"count":100,"action":"进化","objectBeingActed":"大魔法师x20"}]}},{"id":11583,"effectDesc":"送一个招募巨人，送5个招募进阶巨人","batchBar":{"subTitle":"防御神器","batchInfos":[{"count":2,"action":"招募","objectBeingActed":"巨人x4"},{"count":5,"action":"招募","objectBeingActed":"进阶巨人"},{"count":100,"action":"招募","objectBeingActed":"终极巨人x20"}]}}]
*/

// GiftTopStr 礼物置顶
func GiftTopStr(appid, appSecret, roomCode, giftList string, giftExtendInfo []GiftExtendInfo) GiftTopRes {
	url := "https://open.kuaishou.com/openapi/developer/live/interactive/gift/top" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	bytes, _ := json.Marshal(giftExtendInfo)

	Sign := GetSign(map[string]string{
		"app_id":         appid,
		"roomCode":       roomCode,
		"giftList":       giftList,
		"giftExtendInfo": string(bytes),
		"timestamp":      strconv.FormatInt(timestamp/1e6, 10),
	}, appSecret)

	data := GiftTopReq{
		RoomCode:       roomCode,
		Timestamp:      timestamp,
		GiftList:       giftList,
		Sign:           Sign,
		GiftExtendInfo: giftExtendInfo,
	}
	marshal, _ := json.Marshal(data)

	payload := strings.NewReader(string(marshal))

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp GiftTopRes
	json.Unmarshal(body, &resp)
	return resp
}

// GiftTop 礼物置顶
func GiftTop(appid, appSecret, roomCode, giftList string, giftExtendInfo string) GiftTopRes {
	url := "https://open.kuaishou.com/openapi/developer/live/interactive/gift/top" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	bytes, _ := json.Marshal(giftExtendInfo)
	var Sign string
	var data GiftTopReq
	if giftExtendInfo != "" {
		Sign = GetSign(map[string]string{
			"app_id":         appid,
			"roomCode":       roomCode,
			"giftList":       giftList,
			"giftExtendInfo": string(bytes),
			"timestamp":      strconv.FormatInt(timestamp/1e6, 10),
		}, appSecret)
		data = GiftTopReq{
			RoomCode:       roomCode,
			Timestamp:      timestamp,
			GiftList:       giftList,
			Sign:           Sign,
			GiftExtendInfo: giftExtendInfo,
		}
	} else {
		Sign = GetSign(map[string]string{
			"app_id":    appid,
			"roomCode":  roomCode,
			"giftList":  giftList,
			"timestamp": strconv.FormatInt(timestamp/1e6, 10),
		}, appSecret)
		data = GiftTopReq{
			RoomCode:  roomCode,
			Timestamp: timestamp,
			GiftList:  giftList,
			Sign:      Sign,
		}
	}

	marshal, _ := json.Marshal(data)

	payload := strings.NewReader(string(marshal))

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp GiftTopRes
	json.Unmarshal(body, &resp)
	return resp
}

/*
{"closeQuickInfoBySendGift":false,"quickInfos":[{"buttonColor":"#FE3666","buttonText":"红队","commentText":"红","extraText":"一起玩耍吧"},{"buttonColor":"#326BFB","buttonText":"蓝队","commentText":"蓝","extraText":"一起玩耍吧"}]}
*/
// CommentTop 评论置顶
func CommentTop(appid, appSecret, roomCode, roundId string, commentTopReqData CommentTopReqData) CommentTopRes {
	url := "https://open.kuaishou.com/openapi/developer/live/data/interactive/start" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	bytes, _ := json.Marshal(commentTopReqData)

	Sign := GetSign(map[string]string{
		"app_id":    appid,
		"roomCode":  roomCode,
		"roundId":   roundId,
		"type":      "1",
		"data":      string(bytes),
		"timestamp": strconv.FormatInt(timestamp/1e6, 10),
	}, appSecret)

	data := CommentTopReq{
		RoomCode:  roomCode,
		Timestamp: timestamp,
		Sign:      Sign,
		RoundId:   roundId,
		Type:      "1",
		Data:      commentTopReqData,
	}

	marshal, _ := json.Marshal(data)
	payload := strings.NewReader(string(marshal))
	req, _ := http.NewRequest("POST", url, payload)
	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp CommentTopRes
	json.Unmarshal(body, &resp)
	return resp
}

// CommentTopStr 评论置顶
func CommentTopStr(appid, appSecret, roomCode, roundId string, commentTopReqData string) CommentTopRes {
	url := "https://open.kuaishou.com/openapi/developer/live/data/interactive/start" + AddUrl(appid, Acctoken)
	timestamp := time.Now().UnixNano()
	bytes, _ := json.Marshal(commentTopReqData)
	var Sign string
	var data CommentTopReq
	Sign = GetSign(map[string]string{
		"app_id":    appid,
		"roomCode":  roomCode,
		"roundId":   roundId,
		"type":      "1",
		"data":      string(bytes),
		"timestamp": strconv.FormatInt(timestamp/1e6, 10),
	}, appSecret)
	data = CommentTopReq{
		RoomCode:  roomCode,
		Timestamp: timestamp,
		Sign:      Sign,
		RoundId:   roundId,
		Type:      "1",
		Data:      commentTopReqData,
	}
	marshal, _ := json.Marshal(data)
	payload := strings.NewReader(string(marshal))
	req, _ := http.NewRequest("POST", url, payload)
	req.Header.Add("Content-Type", "application/json;charset=UTF-8")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	var resp CommentTopRes
	json.Unmarshal(body, &resp)
	return resp
}

func AddUrl(appid string, acctoken string) string {
	return "?app_id=" + appid + "&access_token=" + acctoken
}

// 1来了 2发言 3点赞 4送礼 5关注主播

// GiftHandlerMsg 分析礼物信息
func GiftHandlerMsg(data []byte) []DmMsg {
	var msg GiftSendMsg
	var res []DmMsg
	err := json.Unmarshal(data, &msg)
	if err != nil {
		return nil
	}
	for _, v := range msg.Data.Payload {
		msg2 := DmMsg{
			Type:  4,
			Uid:   v.UserInfo.UserId,
			Name:  v.UserInfo.UserName,
			Url:   v.UserInfo.HeadUrl,
			Msg:   "送礼",
			Gift:  v.GiftName,
			Num:   v.GiftCount,
			Price: v.GiftTotalPrice,
		}
		res = append(res, msg2)
	}
	return res
}

// CommentHandlerMsg 分析评论信息
func CommentHandlerMsg(data []byte) []DmMsg {
	var msg CommentSendMsg
	var res []DmMsg
	err := json.Unmarshal(data, &msg)
	if err != nil {
		return nil
	}
	for _, v := range msg.Data.Payload {
		msg2 := DmMsg{
			Type:  2,
			Uid:   v.UserInfo.UserId,
			Name:  v.UserInfo.UserName,
			Url:   v.UserInfo.HeadUrl,
			Msg:   v.Content,
			Gift:  "",
			Num:   0,
			Price: 0,
		}
		res = append(res, msg2)
	}
	return res
}

// LikeHandlerMsg 分析点赞信息
func LikeHandlerMsg(data []byte) []DmMsg {
	var msg LikeSendMsg
	var res []DmMsg
	err := json.Unmarshal(data, &msg)
	if err != nil {
		return nil
	}
	for _, v := range msg.Data.Payload {
		msg2 := DmMsg{
			Type:  3,
			Uid:   v.UserInfo.UserId,
			Name:  v.UserInfo.UserName,
			Url:   v.UserInfo.HeadUrl,
			Msg:   "点赞",
			Gift:  "",
			Num:   v.Count,
			Price: 0,
		}
		res = append(res, msg2)
	}
	return res
}

// FollowHandlerMsg 分析关注信息
func FollowHandlerMsg(data []byte) []DmMsg {
	var msg FollowSendMsg
	var res []DmMsg
	err := json.Unmarshal(data, &msg)
	if err != nil {
		return nil
	}
	for _, v := range msg.Data.Payload {
		msg2 := DmMsg{
			Type:  5,
			Uid:   v.UserInfo.UserId,
			Name:  v.UserInfo.UserName,
			Url:   v.UserInfo.HeadUrl,
			Msg:   "关注",
			Gift:  "",
			Num:   0,
			Price: 0,
		}
		res = append(res, msg2)
	}
	return res
}
